﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using WeiboFilter.KeywordsRelated;
using System.Text.RegularExpressions;

//需要加入停用词
//单词、出现次数、在文中的权重
//按照现在的形式，出现次数出不来了
//现阶段只考虑一级词性

namespace WeiboFilter.KeywordsRelated
{
    public class WordWeight
    {
        public WordWeight() { }
        public WordWeight(string wo, double we)
        {
            word = wo;
            weight = we;
        }
        private string _word;

        public string word
        {
            get { return _word; }
            set { _word = value; }
        }
        private double _weight;//最重要的信息 归一化

        public double weight
        {
            get { return _weight; }
            set { _weight = value; }
        }

    }

    public class KeyWords
    {
        // 源句子
        private string _stringSource;

        //从分词库返回的带词性的单词
        private List<ResultTerm> _terms;

        //带有权重的单词
        private List<WordWeight> _words;

        public List<WordWeight> words
        {
            get { return _words; }
            private set { _words = value; }
        }

        //keyword:weight（未归一化）
        private Dictionary<string, double> dict = new Dictionary<string, double>();


        public KeyWords(string txtSource)
        {
            _stringSource = txtSource;

            stringTrim();//过滤微博杂音

            stringSplit();//提取主题部分，并附加到原微博信息上，达到主题双倍的效果

            _terms = getTerms(_stringSource);//中文分词,得到带词性的单词

            parseTerms(_terms);//计算单词的权重

            summaryKeyWords();
        }

        //虑杂音
        private void stringTrim()
        {
            _stringSource = _stringSource.TrimStart(' ');//过滤前置空格
            Regex rg = new Regex(@"@.*?(:|\s)");
            MatchCollection mc = rg.Matches(_stringSource);
            foreach (Match m in mc)
            {
                _stringSource = _stringSource.Replace(m.Value, " ");
            }
        }

        private void stringSplit()
        {
            Regex rg1 = new Regex("【.*?】");//先搜主题1
            Regex rg2 = new Regex("#.*?#");//再搜主题2

            MatchCollection mc = rg1.Matches(_stringSource);
            MatchCollection mc2 = rg2.Matches(_stringSource);

            foreach (Match m in mc)
            {
                _stringSource += m.Value;
            }

            foreach (Match m in mc2)
            {
                _stringSource += m.Value;
            }
        }


        private List<ResultTerm> getTerms(string source)
        {
            if (source == null) return null;
            ICTCLAS clas = ICTCLAS.GetInstance();
            return clas.Segment(source);
        }


        private void parseTerms(List<ResultTerm> terms)
        {
            if (terms == null) return;

            foreach (ResultTerm rt in terms)
            {
                //是停用词则除去
                if (StopWord.stopwords.ContainsKey(rt.Word))
                {
                    continue;
                }

                //首字符 n v a,只考虑 名词、动词、形容词
                string pos = rt.POSStr.Substring(0, 1);
                if (CiXing.cxList.ContainsKey(pos))
                {
                    if (dict.ContainsKey(rt.Word))
                    {
                        dict[rt.Word] += CiXing.cxList[pos];
                    }
                    else
                    {
                        dict[rt.Word] = CiXing.cxList[pos];
                    }
                }

            }
        }

        /// <summary>
        /// 总的来说就是总结权重，比如频率、是否是主题中的单词等，权重累加就可以了,简单，以后只需要归一化
        /// </summary>
        private void summaryKeyWords()
        {
            words = new List<WordWeight>();//关键字数组
            double sum = 0;
            foreach (KeyValuePair<string, double> kv in dict)
            {
                sum += kv.Value;
                words.Add(new WordWeight(kv.Key, kv.Value));
            }

            //归一化权重
            foreach (WordWeight k in words)
            {
                k.weight = k.weight / sum * 100;
            }
        }


        class CompareByWeight : IComparer<WordWeight>
        {
            public int Compare(WordWeight a, WordWeight b)
            {
                if (a.weight > b.weight)
                    return -1;
                else if (a.weight < b.weight)
                    return 1;
                else return 0;
            }
        }

        public List<WordWeight> getTopNwords(int n)
        {

            words.Sort(new CompareByWeight());
            if (words.Count <= n) return words;
            return words.GetRange(0, n);
        }

    } 
}